<template>
  <div class="session-history-container">
    <!-- 页面标题 -->
    <div class="page-header">
      <h2>用户登录会话管理</h2>
      <div class="header-actions">
        <el-input
          v-model="searchKeyword"
          placeholder="搜索用户名/IP地址"
          prefix-icon="Search"
          class="search-input"
          @keyup.enter="handleSearch"
        />
        <el-button type="primary" @click="handleSearch">
          <el-icon><Search /></el-icon>
          搜索
        </el-button>
        <el-button type="danger" @click="batchLogout" :disabled="selectedSessions.length === 0">
          <el-icon><Delete /></el-icon>
          批量注销
        </el-button>
      </div>
    </div>

    <!-- 统计信息 -->
    <div class="statistics-row">
      <el-card class="stat-card">
        <div class="stat-content">
          <div class="stat-number">{{ totalSessions }}</div>
          <div class="stat-label">总会话数</div>
        </div>
      </el-card>
      <el-card class="stat-card">
        <div class="stat-content">
          <div class="stat-number">{{ activeSessions }}</div>
          <div class="stat-label">活跃会话数</div>
        </div>
      </el-card>
      <el-card class="stat-card">
        <div class="stat-content">
          <div class="stat-number">{{ uniqueUsers }}</div>
          <div class="stat-label">活跃用户数</div>
        </div>
      </el-card>
    </div>

    <!-- 会话列表表格 -->
    <el-card class="table-card">
      <el-table
        ref="tableRef"
        :data="sessionsData"
        style="width: 100%"
        v-loading="loading"
        element-loading-text="加载中..."
        border
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55"></el-table-column>
        
        <el-table-column prop="sessionId" label="会话ID" width="180">
          <template #default="scope">
            <span class="session-id">{{ scope.row.sessionId }}</span>
          </template>
        </el-table-column>
        
        <el-table-column prop="username" label="用户名" width="120"></el-table-column>
        
        <el-table-column prop="ipAddress" label="IP地址" width="120"></el-table-column>
        
        <el-table-column prop="loginTime" label="登录时间" width="180">
          <template #default="scope">
            {{ formatDateTime(scope.row.loginTime) }}
          </template>
        </el-table-column>
        
        <el-table-column prop="lastActiveTime" label="最后活跃时间" width="180">
          <template #default="scope">
            {{ formatDateTime(scope.row.lastActiveTime) }}
          </template>
        </el-table-column>
        
        <el-table-column prop="deviceInfo" label="设备信息" min-width="200"></el-table-column>
        
        <el-table-column prop="status" label="状态" width="80">
          <template #default="scope">
            <el-tag :type="scope.row.status === 'active' ? 'success' : 'danger'">
              {{ scope.row.status === 'active' ? '活跃' : '已结束' }}
            </el-tag>
          </template>
        </el-table-column>
        
        <el-table-column label="操作" width="120" fixed="right">
          <template #default="scope">
            <el-button
              type="danger"
              text
              @click="handleLogout(scope.row)"
              :disabled="scope.row.status !== 'active'"
            >
              {{ scope.row.status === 'active' ? '注销' : '已注销' }}
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页控件 -->
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          :total="totalSessions"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search, Delete } from '@element-plus/icons-vue'

// 表格引用
const tableRef = ref(null)

// 加载状态
const loading = ref(false)

// 搜索关键词
const searchKeyword = ref('')

// 分页数据
const currentPage = ref(1)
const pageSize = ref(20)

// 选中的会话
const selectedSessions = ref([])

// 会话数据
const sessionsData = ref([])

// 统计数据
const totalSessions = ref(0)
const activeSessions = ref(0)
const uniqueUsers = ref(0)

// 格式化日期时间
const formatDateTime = (dateTime) => {
  if (!dateTime) return ''
  const date = new Date(dateTime)
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  })
}

// 生成模拟会话数据
const generateMockSessions = () => {
  const sessions = []
  const usernames = ['admin', 'user1', 'user2', 'user3', 'user4', 'user5', 'user6', 'user7', 'user8', 'user9']
  const devices = ['Chrome/90.0.4430.212 Windows 10', 'Firefox/88.0 Windows 10', 'Safari/14.1 macOS 11.3', 'Edge/90.0.818.66 Windows 10', 'Mobile Safari/14.4 iOS 14.4']
  
  // 生成100条模拟数据
  for (let i = 1; i <= 100; i++) {
    const randomDays = Math.floor(Math.random() * 30)
    const randomHours = Math.floor(Math.random() * 24)
    const randomMinutes = Math.floor(Math.random() * 60)
    
    const loginTime = new Date()
    loginTime.setDate(loginTime.getDate() - randomDays)
    loginTime.setHours(loginTime.getHours() - randomHours)
    loginTime.setMinutes(loginTime.getMinutes() - randomMinutes)
    
    const lastActiveTime = new Date(loginTime)
    lastActiveTime.setHours(lastActiveTime.getHours() + Math.floor(Math.random() * 12))
    lastActiveTime.setMinutes(lastActiveTime.getMinutes() + Math.floor(Math.random() * 60))
    
    // 随机决定会话状态，80%的概率为活跃
    const isActive = Math.random() < 0.8
    
    // 生成随机IP地址
    const ipAddress = `192.168.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}`
    
    sessions.push({
      id: i,
      sessionId: `session_${Date.now()}_${i}`,
      username: usernames[Math.floor(Math.random() * usernames.length)],
      ipAddress: ipAddress,
      loginTime: loginTime.toISOString(),
      lastActiveTime: isActive ? new Date().toISOString() : lastActiveTime.toISOString(),
      deviceInfo: devices[Math.floor(Math.random() * devices.length)],
      status: isActive ? 'active' : 'inactive'
    })
  }
  
  // 按登录时间倒序排列
  sessions.sort((a, b) => new Date(b.loginTime) - new Date(a.loginTime))
  
  return sessions
}

// 加载会话数据
const loadSessions = () => {
  loading.value = true
  
  // 模拟API请求延迟
  setTimeout(() => {
    let allSessions = generateMockSessions()
    
    // 应用搜索筛选
    if (searchKeyword.value) {
      const keyword = searchKeyword.value.toLowerCase()
      allSessions = allSessions.filter(session => 
        session.username.toLowerCase().includes(keyword) || 
        session.ipAddress.includes(keyword)
      )
    }
    
    // 计算统计数据
    totalSessions.value = allSessions.length
    activeSessions.value = allSessions.filter(session => session.status === 'active').length
    
    // 计算唯一用户数
    const uniqueUserSet = new Set(allSessions.map(session => session.username))
    uniqueUsers.value = uniqueUserSet.size
    
    // 应用分页
    const startIndex = (currentPage.value - 1) * pageSize.value
    const endIndex = startIndex + pageSize.value
    sessionsData.value = allSessions.slice(startIndex, endIndex)
    
    loading.value = false
  }, 500)
}

// 处理搜索
const handleSearch = () => {
  currentPage.value = 1
  loadSessions()
}

// 处理分页大小变化
const handleSizeChange = (newSize) => {
  pageSize.value = newSize
  loadSessions()
}

// 处理当前页码变化
const handleCurrentChange = (newPage) => {
  currentPage.value = newPage
  loadSessions()
}

// 处理选择变化
const handleSelectionChange = (selection) => {
  selectedSessions.value = selection
}

// 处理单个会话注销
const handleLogout = async (session) => {
  try {
    await ElMessageBox.confirm(
      `确定要注销用户 ${session.username} 的登录会话吗？`,
      '确认注销',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )
    
    // 模拟注销操作
    const index = sessionsData.value.findIndex(item => item.id === session.id)
    if (index !== -1) {
      sessionsData.value[index].status = 'inactive'
      sessionsData.value[index].lastActiveTime = new Date().toISOString()
      
      // 更新统计数据
      activeSessions.value--
      
      ElMessage.success(`已成功注销用户 ${session.username} 的会话`)
    }
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('注销失败，请重试')
    }
  }
}

// 批量注销会话
const batchLogout = async () => {
  if (selectedSessions.value.length === 0) {
    ElMessage.warning('请先选择要注销的会话')
    return
  }
  
  try {
    await ElMessageBox.confirm(
      `确定要注销选中的 ${selectedSessions.value.length} 个会话吗？`,
      '批量注销确认',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )
    
    // 模拟批量注销操作
    selectedSessions.value.forEach(selected => {
      const index = sessionsData.value.findIndex(item => item.id === selected.id)
      if (index !== -1) {
        sessionsData.value[index].status = 'inactive'
        sessionsData.value[index].lastActiveTime = new Date().toISOString()
      }
    })
    
    // 更新统计数据
    activeSessions.value -= selectedSessions.value.length
    
    // 清空选择
    selectedSessions.value = []
    
    ElMessage.success(`已成功注销 ${selectedSessions.value.length} 个会话`)
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('批量注销失败，请重试')
    }
  }
}

// 页面加载时初始化
onMounted(() => {
  loadSessions()
})
</script>

<style scoped>
.session-history-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  padding: 0;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding: 0;
}

.page-header h2 {
  margin: 0;
  color: #303133;
  font-size: 20px;
  font-weight: 600;
}

.header-actions {
  display: flex;
  align-items: center;
  gap: 12px;
}

.search-input {
  width: 240px;
}

.statistics-row {
  display: flex;
  gap: 20px;
  margin-bottom: 20px;
}

.stat-card {
  flex: 1;
  background-color: #f0f9ff;
  border-color: #91d5ff;
}

.stat-content {
  text-align: center;
  padding: 16px 0;
}

.stat-number {
  font-size: 28px;
  font-weight: 700;
  color: #1890ff;
  line-height: 1;
  margin-bottom: 8px;
}

.stat-label {
  font-size: 14px;
  color: #666;
}

.table-card {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.session-id {
  font-family: 'Courier New', monospace;
  font-size: 12px;
  color: #666;
  word-break: break-all;
}

.pagination-container {
  margin-top: 16px;
  display: flex;
  justify-content: flex-end;
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .statistics-row {
    flex-wrap: wrap;
  }
  
  .stat-card {
    flex: 1 1 calc(50% - 10px);
    min-width: 200px;
  }
}

@media (max-width: 768px) {
  .page-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }
  
  .header-actions {
    width: 100%;
    flex-wrap: wrap;
  }
  
  .search-input {
    width: 100%;
  }
  
  .statistics-row {
    flex-direction: column;
  }
  
  .stat-card {
    flex: 1 1 100%;
  }
}
</style>